package com.zhike.api.controller.file;

import java.io.File;
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.zhike.common.constant.SysConfigConstants;
import com.zhike.common.dto.R;
import com.zhike.common.dto.SearchFileDTO;
import com.zhike.common.enums.ResultCode;
import com.zhike.common.enums.YesNoEnum;
import com.zhike.common.exception.ZkimException;
import com.zhike.common.repository.FileUploadLog;
import com.zhike.common.vo.UserInfo4Cache;
import com.zhike.service.file.IFileService;
import com.zhike.service.group.IGroupService;
import com.zhike.service.system.ISystemConfigService;
import com.zhike.service.system.ISystemService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.parameters.RequestBody;

@RestController
@RequestMapping("/api/zkim/file")
@Api(tags = "文件模块")
public class FileController {
  @Resource
  private IFileService fileService;

  @Autowired
  private ISystemService systemService;

  @Autowired
  private IGroupService groupService;

  @Autowired
  private ISystemConfigService systemConfigService;


  @GetMapping("/vframes")
  public ResponseEntity<byte[]> getFrame(@RequestParam String videoUrl, @RequestParam int offset) {
    Integer conf = systemConfigService.getValueByKeyAsInt(SysConfigConstants.CONFIG_TYPE_SECURITY,
        SysConfigConstants.CONFIG_MESSAGE);
    if (conf != null && conf.equals(YesNoEnum.NO.getValue())) {
      return new ResponseEntity<>(HttpStatus.OK);
    }

    try {
      // 调用FFmpeg提取帧
      String outputFilePath = extractFrame(videoUrl, offset);

      // 读取文件内容
      Path path = Paths.get(outputFilePath);
      byte[] imageBytes = Files.readAllBytes(path);

      // 删除临时文件
      Files.delete(path);

      // 设置响应头
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.IMAGE_JPEG);

      // 返回图片
      return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
    } catch (IOException e) {
      e.printStackTrace();
      return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  private String extractFrame(String videoUrl, int offset) throws IOException {
    // 生成输出文件路径
    String outputFilePath = "/opt/output/frame_" + System.currentTimeMillis() + ".jpg";
    File outputDir = new File("/opt/output");
    if (!outputDir.exists()) {
      outputDir.mkdirs();
    }

    // 构建FFmpeg命令
    ProcessBuilder processBuilder = new ProcessBuilder(
        "ffmpeg",
        "-ss", String.valueOf(offset),
        "-i", videoUrl,
        "-vframes", "1",
        "-q:v", "2",
        outputFilePath);

    // 执行命令
    Process process = processBuilder.start();
    try {
      process.waitFor();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    return outputFilePath;
  }

  @PostMapping("userAvatarUploader")
  @ApiOperation(value = "用户头像上传", notes = "用户头像修改")
  public R<HashMap<String, Object>> userAvatarUploader(@RequestParam("file") MultipartFile file)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.userAvatarUploader(file, uc.getFakeUid()));
  }

  @ApiOperation(value = "群头像上传", notes = "群头像修改")
  @PostMapping("groupAvatarUploader")
  public R<HashMap<String, Object>> groupAvatarUploader(@RequestParam("file") MultipartFile file, String groupId)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    if (!groupService.isGroupOwner(groupId, uc.getFakeUid()) && !groupService.isGroupAdmin(groupId, uc.getFakeUid())) {
      throw new ZkimException(ResultCode.GROUP_NORIGHT);
    }
    return R.success(fileService.groupAvatarUploader(file, uc.getFakeUid(), groupId));
  }

  @PostMapping("msgImageUploader")
  @ApiOperation(value = "聊天图片上传")
  public R<HashMap<String, Object>> msgImageUploader(@RequestParam("file") MultipartFile file)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.msgImageUploader(file, uc.getFakeUid()));
  }

  @PostMapping("msgVideoUploader")
  @ApiOperation(value = "聊天视频上传", notes = "聊天视频上传")
  public R<HashMap<String, Object>> msgVideoUploader(@RequestParam("file") MultipartFile file)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.shortVideoUploader(file, uc.getFakeUid()));
  }

  @PostMapping("msgVoiceUploader")
  @ApiOperation(value = "聊天音频上传")
  public R<HashMap<String, Object>> voiceUploader(@RequestParam("file") MultipartFile file)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.msgVoiceUploader(file, uc.getFakeUid()));
  }

  @PostMapping("attachmentUploader")
  @ApiOperation(value = "附件上传")
  public R<HashMap<String, Object>> attachmentUploader(@RequestParam("file") MultipartFile file)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.fileAttachment(file, uc.getFakeUid()));
  }

  @PostMapping("attachmentUploaders")
  @ApiOperation(value = "批量附件上传")
  public R<List<HashMap<String, Object>>> attachmentUploaders(@RequestParam("files") MultipartFile[] files)
      throws ServletException, IOException {
    UserInfo4Cache uc = systemService.getUserInfo();
    List<HashMap<String, Object>> res = new ArrayList<>();
    for (MultipartFile file : files) {
      if (!file.isEmpty()) {
        res.add(fileService.fileAttachment(file, uc.getFakeUid()));
      }
    }
    return R.success(res);
  }

  @ApiOperation(value = "我的文件列表")
  @PostMapping("myFiles")
  public R<List<FileUploadLog>> myUploadFiles(@RequestBody SearchFileDTO dto) {
    UserInfo4Cache uc = systemService.getUserInfo();
    return R.success(fileService.selectMyFiles(uc.getFakeUid(), dto.getFileName()));
  }

  @ApiOperation(value = "用户头像图片下载")
  @GetMapping("avatarDownload")
  public void avatarDownload(@Validated @RequestParam(value = "uid", required = true) String uid,
      HttpServletResponse res)
      throws IOException {
    fileService.userAvatarDown(uid, res);
  }

  @ApiOperation(value = "获取kkfileview文件预览路径")
  @GetMapping("getAttachmentDownloadUrl")
  public R<String> getAttachmentDownloadUrl(@Validated @RequestParam(value = "fileKey", required = true) String fileKey,
                             HttpServletResponse res) {

    return R.success( fileService.getAttachmentDownloadUrl(fileKey, res));
  }

  @ApiOperation(value = "群头像图片下载")
  @GetMapping("groupAvatarDownload")
  public void groupAvatarDownload(@Validated @RequestParam(value = "groupId", required = true) String groupId,
      HttpServletResponse res)
      throws IOException {
    fileService.groupAvatarDown(groupId, res);
  }
}
